#include "hashtable.h"
#include <cstdio>

//argv[1]->hashing_strategy 1:naive 2:ascii 3:utf-8
//argc[2]->collision_strategy  1:linear_prob 2:quaduadic_prob 3:public_overflow

int main(int argc, char *argv[])
{
    FILE *fin = fopen("2.in", "r");
    FILE *fout = fopen("2.out", "w");
    if (argv[1][0] == '1' && argv[2][0] == '1')
    {
        fprintf(fout, "naive,linear\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new naive_hashing(), new linear_probe());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data), false);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,false));
            }
            else
                break;
        }
    }
    else if (argv[1][0] == '1' && argv[2][0] == '2')
    {
        fprintf(fout, "naive,quaduadic\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new naive_hashing(), new quaduatic_probing_collision_strategy());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data), false);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,false));
            }
            else
                break;
        }
    }
    else if (argv[1][0] == '1' && argv[2][0] == '3')
    {
        fprintf(fout, "naive,overflow\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new naive_hashing(), new public_overflow_collision_strategy());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data), true);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,true));
            }
            else
                break;
        }
    }
    else if (argv[1][0] == '2' && argv[2][0] == '1')
    {
        fprintf(fout, "ascii,linear\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new ascii_hashing_strategy(), new linear_probe());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data), false);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,false));
            }
            else
                break;
        }
    }
    else if (argv[1][0] == '2' && argv[2][0] == '2')
    {
        fprintf(fout, "ascii,quaduatic\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new ascii_hashing_strategy(), new quaduatic_probing_collision_strategy());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data), false);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,false));
            }
            else
                break;
        }
    }
    else if (argv[1][0] == '2' && argv[2][0] == '3')
    {
        fprintf(fout, "ascii,overflow\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new ascii_hashing_strategy(), new public_overflow_collision_strategy());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data), true);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,true));
            }
            else
                break;
        }
    }
    else if (argv[1][0] == '3' && argv[2][0] == '1')
    {
        fprintf(fout, "utf8,linear\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new utf8_hashing_strategy(), new linear_probe());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data), false);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,false));
            }
            else
                break;
        }
    }
    else if (argv[1][0] == '3' && argv[2][0] == '2')
    {
        fprintf(fout, "utf8,quaduatic\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new utf8_hashing_strategy(), new quaduatic_probing_collision_strategy());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data), false);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,false));
            }
            else
                break;
        }
    }
    else if (argv[1][0] == '3' && argv[2][0] == '3')
    {
        fprintf(fout, "utf8,overflow\n");
        int type;
        char buffer[1000];
        int data;
        hashtable table(TABLE_SIZE, new utf8_hashing_strategy(), new public_overflow_collision_strategy());
        while (true)
        {
            fscanf(fin, "%d", &type);
            if (type == 0)
            {
                fscanf(fin, "%s", buffer);
                fscanf(fin, "%d", &data);
                table.insert(hash_entry(buffer, data),true);
            }
            else if (type == 1)
            {
                fscanf(fin, "%s", buffer);
                fprintf(fout, "%d\n", table.query(buffer,true));
            }
            else
                break;
        }
    }
    return 0;
}